package com.mindskip.xzs.exception;

import com.mindskip.xzs.utility.RestResponse;
import com.mindskip.xzs.domain.enums.SystemCode;
import com.mindskip.xzs.utility.ErrorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.stream.Collectors;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    // 当对带有 @Valid 的参数的验证失败时抛出异常进行捕获
    // 前端提交的方式为json格式有效
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RestResponse<Object> handler(MethodArgumentNotValidException e) {
        // 将所有参数错误都拼接成字符串
        String errorMsg = e.getBindingResult().getAllErrors()
                .stream()
                .map(file -> {
                    FieldError fieldError = (FieldError) file;
                    return ErrorUtil.parameterErrorFormat(fieldError.getField(), fieldError.getDefaultMessage());
                })
                .collect(Collectors.joining());
        return new RestResponse<>(SystemCode.ParameterValidError.getCode(), errorMsg);
    }

    // 当对带有 @Valid 的参数的验证失败时抛出异常进行捕获
    // 仅对于表单提交有效，对于以json格式提交将会失效
    @ExceptionHandler(BindException.class)
    public RestResponse<Object> handler(BindException e) {
        String errorMsg = e.getBindingResult().getAllErrors()
                .stream()
                .map(file -> {
                    FieldError fieldError = (FieldError) file;
                    return ErrorUtil.parameterErrorFormat(fieldError.getField(), fieldError.getDefaultMessage());
                })
                .collect(Collectors.joining());
        return new RestResponse<>(SystemCode.ParameterValidError.getCode(), errorMsg);
    }

    @ExceptionHandler(ParameterValidException.class)
    public RestResponse<Object> handler(ParameterValidException e) {
        return new RestResponse<>(SystemCode.ParameterValidError.getCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public RestResponse<Object> handler(Exception e) {
        log.error("出现业务异常：" + e.getMessage());
        return new RestResponse<>(SystemCode.InnerError.getCode(), SystemCode.InnerError.getMessage());
    }
}
